//============================================================================//
// [ KeyAction ]                                                       [樹招] //
//============================================================================//

// Ver.0.04 (2007/04/07)

//----------------------------------------------------------------------------//
// SetKeyAction EventID Key [SubroutineName [P1 P2 P3...]]
//  -> KeyActionを設定する。
//------------------------------------//
SetKeyAction:
	Local data_cnt = Count(KA_KeyAction) + 1
	Local data_id = IIf(Args(1) != "", Args(1), "NO_ID")
	Local data = KA_SetEventData(3)
	Local key = Args(2)
	
	// KeyAcitonを登録する
	Set KA_KeyAction[data_cnt] List("(" & data_id & ")", "(" & key & ")", "(" & data & ")")
	// IDを登録する
	Call KA_SetEventID data_id data_cnt
Return


//----------------------------------------------------------------------------//
// ClearKeyAction [option] or ClearKeyAction [type (id or number)]
//  -> KeyActionを初期化する。 or 特定のKeyActionを削除する。
//------------------------------------//
ClearKA:
ClearKeyAction:
	Switch LCase(Args(1))
	Case "keyaction"
		// KeyActionを削除する
		Call ClearKA_KeyAction "KeyAction"
	Case "reserve"
		// KeyActionを一時的に別配列に保存する
		Call ClearKA_Reserve
		Call ClearKA_Info Args(2)
	Case "restore"
		// 保存したKeyActionを復元する
		Call ClearKA_Restore
		Call ClearKA_Info Args(2)
	Case Else
		// KeyActionを初期化する
		Call ClearKA_KeyAction
		Call ClearKA_Stack
		Call ClearKA_Info Args(1)
	EndSw
Return


//-- ClearKA_KeyAction [(id or number)] : 指定したKeyActionを削除する --//
ClearKA_KeyAction:
	If ArgNum = 0 Then
		// 引数が0の場合はKeyActionを全て削除して終了する
		UnSet KA_KeyAction
		UnSet KA_KeyActionID
		Return
	ElseIf Count(KA_KeyAction) = 0 Then
		// イベントデータが存在しない場合は終了する
		Return
	EndIf
	
	UpVar
	
	// 削除対象の番号を設定する
	Local remove_num i
	For i = 3 To ArgNum
		If IsNumeric(Args(i)) Then
			remove_num = remove_num & " " & Args(i)
		ElseIf IsVarDefined(KA_KeyActionID[Args(i)]) Then
			remove_num = remove_num & " " & KA_KeyActionID[Args(i)]
		EndIf
	Next
	remove_num = Trim(remove_num)
	
	If remove_num = "" Then
		Return  // 削除対象が設定されない場合は終了する
	EndIf
	
	// イベントリストを一時的に退避させる
	CopyArray KA_KeyAction KA_Temporary
	UnSet KA_KeyAction
	UnSet KA_KeyActionID
	
	// 削除対象以外を再設定する
	Local idx = 1
	For i = 1 To Count(KA_Temporary)
		If LSearch(remove_num, i) = 0 Then
			Set KA_KeyAction[idx] KA_Temporary[i]
			Call KA_SetEventID LIndex(KA_Temporary[i], 1) idx
			Incr idx 1
		EndIf
	Next
	
	// 不必要になった変数を削除する
	UnSet KA_Temporary
Return


//-- ClearKA_Reserve : KeyActionを一時的に別配列に保存する --//
ClearKA_Reserve:
	If Count(KA_KeyAction) = 0 Then
		Return  // KeyActionが設定されていない場合は終了する
	EndIf
	
	// 保存数を記録する
	Incr KA_StackCount 1
	
	// KeyActionを保存する
	CopyArray KA_KeyAction Eval("KA_KeyAction_Stack" & KA_StackCount)
	CopyArray KA_KeyActionID Eval("KA_KeyActionID_Stack" & KA_StackCount)
	
	// KeyActionを初期化する
	Call ClearKA_KeyAction
Return


//-- ClearKA_Restore : 保存したKeyActionを復元する --//
ClearKA_Restore:
	// KeyActionを初期化する
	Call ClearKA_KeyAction
	
	If Not IsVarDefined(KA_StackCount) Then
		Return  // 保存したKeyActionが0の場合は終了する
	EndIf
	
	// KeyActionを復元する
	CopyArray Eval("KA_KeyAction_Stack" & KA_StackCount) KA_KeyAction
	CopyArray Eval("KA_KeyActionID_Stack" & KA_StackCount) KA_KeyActionID
	UnSet Eval("KA_KeyAction_Stack" & KA_StackCount)
	UnSet Eval("KA_KeyActionID_Stack" & KA_StackCount)
	
	// StackCountが1なら変数を削除する
	If KA_StackCount = 1 Then
		UnSet KA_StackCount
	Else
		Incr KA_StackCount -1
	EndIf
Return


//-- ClearKA_Stack : 保存情報を破棄する --//
ClearKA_Stack:
	If Not IsVarDefined(KA_StackCount) Then
		Return  // 保存したKeyActionが0の場合は終了する
	EndIf
	
	Local i
	For i = 1 To KA_StackCount
		UnSet Eval("KA_KeyAction_Stack" & i)
		UnSet Eval("KA_KeyActionID_Stack" & i)
	Next
Return


//-- ClearKA_Info [option] : 情報変数の破棄する --//
ClearKA_Info:
	If LCase(Args(1)) != "keep" Then
		UnSet KA_Select
	EndIf
	UnSet KA_NowKeyID
Return


//----------------------------------------------------------------------------//
// WaitKeyAction [var_name]
//  -> "Wait Click"の代わり。色々と面倒な人用。
//------------------------------------//
WaitKeyAction:
	Local var_name = IIf(Args(1) != "", Args(1), "KA_Select")
	
	// 選択結果を初期化する
	Eval(var_name) = ""
	
	// 設定したキーが押されているか確認する
	Wait Click
	Call ProcessKeyAction var_name
Return


//----------------------------------------------------------------------------//
// ProcessKeyAction [var_name]
//  -> 設定されたキーのイベントの処理を行う。
//------------------------------------//
ProcessKeyAction:
	If (Count(KA_KeyAction) = 0) Then
		Return  // KeyActionが存在しない場合は終了する
	EndIf
	
	Local var_name = IIf(Args(1) != "", Args(1), "KA_Select")
	Local event i
	
	// 該当キーが押されているKeyActionを検索する
	For i = 1 To Count(KA_KeyAction)
		If Not KA_KeyListState(LIndex(KA_KeyAction[i], 2)) Then
			Skip  // キーが押されていなければスキップする
		EndIf
		
		// キーが押されているイベントを実行する
		Set KA_NowKeyID i
		Eval(var_name) = LIndex(KA_KeyAction[i], 1)
		
		// イベントサブルーチンが設定されている場合は呼び出す
		If LIndex(KA_KeyAction[i], 3) != "" Then
			event = Eval(LIndex(KA_KeyAction[i], 3))
		EndIf
		
		Break
	Next
Return


//----------------------------------------------------------------------------//
// KeyAction Function
//----------------------------------------------------------------------------//

//-- SetEventID id number : イベントIDを登録する --//
KA_SetEventID:
	Local data_id = Args(1)
	
	// IDを登録する
	Set KA_KeyActionID[data_id] Trim(KA_KeyActionID[data_id] & " " & Args(2))
	
	// リスト式のIDはリストの一番目もIDとして登録する
	If LLength(data_id) > 1 Then
		data_id = LIndex(data_id, 1)
		Set KA_KeyActionID[data_id] Trim(KA_KeyActionID[data_id] & " " & Args(2))
	EndIf
Return


//-- SetEventData(start_idx) : サブルーチン名とその引数を関数の形にして返す --//
KA_SetEventData:
	UpVar
	
	Local start_idx = Args(1) + 1
	Local name = Args(start_idx)
	Local data i
	
	If LCase(name) = "_copymousepoint" Then
		Return KA_CopyMousePoint(Args(start_idx + 1))
	ElseIf name = "" Then
		Return ""  // サブルーチン名がなければ空文字列を返す
	EndIf
	
	// 引数を連結する
	For i = (start_idx + 1) To ArgNum
		data = data & ",`" & Args(i) & "`"
	Next
Return (name & "(" & Mid(data, 2) & ")")


//-- CopyMousePoint(number) : MousePointのEventDataから設定する --//
KA_CopyMousePoint:
	Local num = Args(1)
	
	// IDリストから番号を取り出す
	If IsVarDefined(MP_ClickPointID[Args(1)]) Then
		num = LIndex(MP_ClickPointID[Args(1)], 1)
	EndIf
	
	If IsVarDefined(MP_ClickPoint[num]) Then
		Return LIndex(MP_ClickPoint[num], 7)
	EndIf
Return ""


//-- KeyListState(key_list) : 指定されたKeyが押されているなら[1]を返す --//
KA_KeyListState:
	Local mode = (Left(Args(1), 1) = "*")
	Local cnt = IIf(mode = 1, 0, -1)
	Local key = IIf(mode = 1, Mid(Args(1), 2), Args(1))
	Local i
	
	// 先頭に"*"があるならAndで判定する
	For i = 1 To LLength(key)
		If KeyState(LIndex(key, i)) Then
			If mode = 1 Then
				Incr cnt 1
			Else
				Return 1
			EndIf
		EndIf
	Next
Return (cnt = LLength(key))


